using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DuctTape : MonoBehaviour {

	public MeshFilter 	meshFilter;
	public bool 		drawGismoid = false;
	public bool 		change 		= false;
	public float 		scrapDistance = 0.5f;
	public float 		stretchDistance = 0.5f;
	public float 		targetDistanceModifier = 2f;
	//public int raySpreadTries = 10;
	
	private Mesh 		mesh;
	private Vector3[] 	vertices;
	private List<Ray> 	raylist 	= new List<Ray>();
	private List<Vector3> 	hitlist 	= new List<Vector3>();
	private List<Vector3> rayTries = new List<Vector3>();
	
	public Transform target;
	

	// Use this for initialization
	void Start () {
//		//Vector3 dir = direction.forward;
//		
//		//Get Mesh
//		mesh = GetComponent<MeshFilter>().mesh;
//		//Get vertice list
//		vertices = mesh.vertices;
//		//Loop all vertices and raycast straight down to find new position. Dont forget to scale.
//		//TODO: Direction
//		for(int i = 0;i<vertices.Length;i++){
//			//Get one vertice
//			Vector3 vert = vertices[i];
//			//Create temp for scaling
//			Vector3 temp = vert;
//			//Create the scale and resore y-scale
//			Vector3 scale = transform.lossyScale;
//			//scale.y = 1;
//			//Scale
//			temp = Vector3.Scale(temp,scale);
//			temp = transform.rotation*temp;
//			//calculate where to throw rays from temp
//			Ray ray = new Ray(new Vector3(transform.position.x+temp.x,transform.position.y+temp.y,transform.position.z+temp.z),target.position-(transform.position+temp));
//			
//			RaycastHit hit = new RaycastHit();
//			//add ray to raylist for debug
//			raylist.Add (ray);
//			//Throw rays and if it's a hit set new position.
//			//TODO: Set all positions depending on point when casting with direction
//			if(Physics.Raycast(ray,out hit,1000f)){
//				hitlist.Add(hit.point);
//				vert = hit.point-(transform.position+vert);
//				//vert += (target.position-(transform.position+temp))*0.01f;
//				vertices[i] = vert;
//			}else{
//				Debug.Log("missed :S");
//			}
//			//TODO: change position then recast against centerpoint when we have direction
////			else{
////				vert.y +=-0.3f;
////				vert.y +=0.01f;
////				vertices[i] = vert;
////			}
//		}
//			//Set mesh vertice list and meshfilter then recalculate bound and normals
//			for(int i = 0 ;i<hitlist.Count;i++){
//				vertices[i] = (hitlist[i]-transform.position)*0.8f;
//				Vector3 temp = vertices[i];
//				//temp.y += 0.01f;
//				vertices[i] = temp;
//			}
//		
//			mesh.vertices = vertices;
//			GetComponent<MeshFilter>().mesh = mesh;
//			mesh.RecalculateBounds();
//			mesh.RecalculateNormals();
//			transform.localScale = new Vector3(1,1,1);
//			transform.rotation =Quaternion.identity;
	}
	
	public bool tape(Transform t){
		target = t;
		hitlist.Clear();
		//Vector3 dir = direction.forward;
		Debug.Log("Taping");
		//Get Mesh
		mesh = GetComponent<MeshFilter>().mesh;
		//Get vertice list
		vertices = mesh.vertices;
		//Loop all vertices and raycast straight down to find new position. Dont forget to scale.
		for(int i = 0;i<vertices.Length;i++){
			//Get one vertice
			Vector3 vert = vertices[i];
			//Create temp for scaling
			Vector3 temp = vert;
			//Create the scale and resore y-scale
			Vector3 scale = transform.lossyScale;
			temp = Vector3.Scale(temp,scale);
			temp = transform.rotation*temp;
			//calculate where to throw rays from temp
			Ray ray = new Ray(
				new Vector3(transform.position.x+temp.x,transform.position.y+temp.y,transform.position.z+temp.z),
				(target.position-(transform.position+temp))*targetDistanceModifier
			);
			
			RaycastHit hit = new RaycastHit();
			//add ray to raylist for debug
			raylist.Add (ray);
			if(Physics.Raycast(ray, out hit, 1000f, 1 << LayerMgr.LAYER_BUILD)){
				hitlist.Add(hit.point);
				vert = hit.point-(transform.position+vert);
				vertices[i] = vert;
				if((transform.position+vert-target.position).magnitude>scrapDistance){
					Debug.Log("Scraped, distance to far: "+(transform.position+vert-target.position).magnitude);
					return false;
				}
			}else{
				Debug.Log("missed :S");
			}			
		}
			Debug.Log("Vertices: " + vertices.Length + " hitlist: " +hitlist.Count);
			//Set mesh vertice list and meshf1ilter then recalculate bound and normals
			for(int i = 0 ;i<hitlist.Count;i++){
				vertices[i] = (hitlist[i]-transform.position)*(0.95f+Random.Range(0.01f,0.02f));
				Vector3 temp = vertices[i];
				//temp.y += 0.01f;
				vertices[i] = temp;
				//boolit
			}
			for(int i = 1 ;i<vertices.Length;i++){
				Vector3 temp = vertices[i-1];
				for(int j = 1 ;j<vertices.Length;j++){
				Vector3 temp1 = vertices[j-1];				
					if((temp-temp1).magnitude>stretchDistance){
						Debug.Log((temp-temp1).magnitude);
						Debug.Log("TOO MUCH STRETCH");
						return false;
						
						}
					}
			}
		
			mesh.vertices = vertices;
			GetComponent<MeshFilter>().mesh = mesh;
			mesh.RecalculateBounds();
			mesh.RecalculateNormals();
			transform.localScale = new Vector3(1,1,1);
			transform.rotation =Quaternion.identity;
		
			return true;
	}
//	public void recalculateMesh(){
//	}
	
	void OnDrawGizmos(){
		if(drawGismoid){
			Debug.Log(raylist.Count);
			Gizmos.color = Color.red;
			foreach(Ray r in raylist){
				Gizmos.DrawRay(r);
			}
			Gizmos.color = Color.blue;
			foreach(Vector3 v in hitlist){
				Gizmos.DrawSphere(v,0.002f);
			}
		}
	}
	
}
